package com.sanduche.annotations.processors;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeBuildProcessingEnvImpl;
import org.stjs.generator.STJSTranspiler;

import com.sanduche.annotations.JsExport;

@SupportedAnnotationTypes("com.sanduche.annotations.*")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class SanducheAnnotationProcessor extends AbstractProcessor {

	@SuppressWarnings("restriction")
	@Override
	public boolean process(Set<? extends TypeElement> annotations,
			RoundEnvironment roundEnv) {

		Set<? extends Element> elems = roundEnv
				.getElementsAnnotatedWith(JsExport.class);
		Iterator<? extends Element> it = elems.iterator();
		while (it.hasNext()) {
			Element element = it.next();
			if (element.getKind() == ElementKind.CLASS) {
				TypeElement clazz = (TypeElement) element;
				this.processingEnv.getMessager().printMessage(
						Diagnostic.Kind.NOTE,
						"Procesando: " + clazz.getQualifiedName());

				org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeBuildProcessingEnvImpl env = (IdeBuildProcessingEnvImpl) processingEnv;
				IFile file = env.getEnclosingIFile(clazz);
				IContainer parent = file.getParent();
				while (!parent.getParent().equals(env.getProject()))
					parent = parent.getParent();

				IJavaProject jProject = env.getJavaProject();
				try {
					IClasspathEntry[] classpath = jProject
							.getResolvedClasspath(true);
					List<URL> urls = new ArrayList<URL>();
					for (IClasspathEntry c : classpath)
						urls.add(c.getPath().makeAbsolute().toFile()
								.getCanonicalFile().toURI().toURL());

					urls.add(env
							.getProject()
							.getLocation()
							.append(jProject.getOutputLocation()
									.removeFirstSegments(1)).toFile()
							.getCanonicalFile().toURI().toURL());

					URLClassLoader cl = new URLClassLoader(
							urls.toArray(new URL[urls.size()]), this.getClass()
									.getClassLoader());

					STJSTranspiler.transpileClass(parent.getLocation()
							.toOSString(), clazz.getQualifiedName().toString(),
							cl);

					env.getProject().refreshLocal(IResource.DEPTH_INFINITE,
							null);
				} catch (JavaModelException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (MalformedURLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				this.processingEnv.getMessager().printMessage(
						Diagnostic.Kind.NOTE,
						"Procesado: " + clazz.getQualifiedName());

			}
		}

		return true;
	}
}
